package com.ztmg.common.util;


import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Random;


public class Des3 {
    static {
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
    }

    private static SecureRandom sr = new SecureRandom();
    private static final String MCRYPT_TRIPLEDES = "DESede";
    private static final String TRANSFORMATION = "DESede/CBC/PKCS5Padding";

    public static byte[] decrypt(byte[] data, byte[] key, byte[] iv) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(MCRYPT_TRIPLEDES);
        SecretKey sec = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        IvParameterSpec IvParameters = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, sec, IvParameters);
        return cipher.doFinal(data);
    }

    public static byte[] encrypt(byte[] data, byte[] key, byte[] iv) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey sec = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        IvParameterSpec IvParameters = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, sec, IvParameters);
        return cipher.doFinal(data);
    }

    public static byte[] generateSecretKey() throws NoSuchAlgorithmException {
        KeyGenerator keygen = KeyGenerator.getInstance(MCRYPT_TRIPLEDES);
        return keygen.generateKey().getEncoded();
    }

    public static byte[] randomIVBytes() {
        Random ran = new Random();
        byte[] bytes = new byte[8];
        for (int i = 0; i < bytes.length; ++i) {
            bytes[i] = (byte) ran.nextInt(Byte.MAX_VALUE + 1);
        }
        return bytes;
    }

    public static void main(String args[]) throws Exception {
        String plainText = "a12*&1c中文";
        final byte[] secretBytes = "MzVjZTgxZTQzMDUwNGNiMGExZWJkMWNh".getBytes();

        final byte[] ivbytes = {(byte)'0',(byte)'0',(byte)'0',(byte)'0',(byte)'0',(byte)'0',(byte)'0',(byte)'0'};
        System.out.println("plain text: " + plainText);
        System.out.println("encode text: " +new String(org.apache.commons.codec.binary.Base64.decodeBase64("E4w/jm2f6z8a2WaJMmwQA=="),"UtF-8"));
        System.out.println("encode text: " +new String(org.apache.commons.codec.binary.Base64.decodeBase64("E4w/jm2f6z8a2WaJMmwQA=="),"UtF-8") );
        //byte[] encrypt = Des3.encrypt(plainText.getBytes(), secretBytes, ivbytes);
        byte[] encrypt = Des3.decrypt(org.apache.commons.codec.binary.Base64.decodeBase64("E4w/jm2f6z8a2WaJMmwQA=="),secretBytes,"00000000".getBytes());


        System.out.println("cipher text: " + encrypt);
        System.out.println("decrypt text: " + new String(encrypt, "UtF-8"));
    }
    // 转化字符串为十六进制编码
    public static String toHexString(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = (int) s.charAt(i);
            String s4 = Integer.toHexString(ch);
            str = str + s4;
        }
        return str;
    }

    //转换成十六进制字符串

    public static String byte2hex(byte[] b) {

        String hs = "";

        String stmp = "";

        for (int n = 0; n < b.length; n++) {

            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));

            if (stmp.length() == 1)

                hs = hs + "0" + stmp;

            else

                hs = hs + stmp;

            if (n < b.length - 1)

                hs = hs + ":";

        }

        return hs.toUpperCase();

    }
    /**
     *
     * @Description CBC加密
     * @param key 密钥
     * @param keyiv IV
     * @param data 明文
     * @return Base64编码的密文
     * @throws Exception
     * @author Shindo
     * @date 2016年11月15日 下午5:26:46
     */
    public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }

}
